﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
#if NET40
using System.Net;
#else
using System.Net;
using System.Net.Http;
#endif
using System.Threading.Tasks;
using SAM.Framework.CustomHttpClient;

namespace SAM.Framework.Infrastructure
{
    public class CustomHttpClient : ICustomHttpClient
    {
#if NET40
        #region NET40
        private HttpWebRequest request = null;
        private HttpWebResponse response = null;

        public CustomHttpClient()
        {
        }

        private void SetHttps()
        {
            //处理https都可以验证通过的方法
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback((sender, certificate, chain, errors) =>
            {
                return true;
            });
        }

        public string Get(string url, bool https = false, Dictionary<string, string> cookies = null, Dictionary<string, string> headers = null)
        {
            if (https)
            {
                this.SetHttps();
            }
            request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";
            request.ContentType = "text/html;charset=UTF-8";
            CookieContainer cookieContainer = new CookieContainer();
            if (cookies != null)
            {
                foreach (var cookie in cookies)
                {
                    cookieContainer.Add(new Cookie(cookie.Key, cookie.Value));
                }
                request.CookieContainer = cookieContainer;
            }
            if (headers != null)
            {
                foreach (var header in headers)
                {
                    request.Headers.Add(header.Key, header.Value);
                }
            }

            response = (HttpWebResponse)request.GetResponse();
            Stream strm = response.GetResponseStream();

            StreamReader sr = new StreamReader(strm, Encoding.UTF8);

            string line;

            StringBuilder sb = new StringBuilder();

            while ((line = sr.ReadLine()) != null)
            {
                sb.Append(line + Environment.NewLine);
            }
            sr.Close();
            strm.Close();
            return sb.ToString();
        }

        public string Post(string url, string postData , bool https = false, Dictionary<string, string> cookies = null, Dictionary<string, string> headers = null)
        {
            if (https)
            {
                this.SetHttps();
            }


            byte[] postdatabyte = Encoding.UTF8.GetBytes(postData);

            request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "application/json;charset=UTF-8";
            request.AllowAutoRedirect = false;
            request.KeepAlive = true;
            request.ContentLength = postdatabyte.Length;
            CookieContainer cookieContainer = new CookieContainer();
            if (cookies != null)
            {
                foreach (var cookie in cookies)
                {
                    cookieContainer.Add(new Cookie(cookie.Key, cookie.Value));
                }
                request.CookieContainer = cookieContainer;
            }
            if (headers != null)
            {
                foreach (var header in headers)
                {
                    request.Headers.Add(header.Key, header.Value);
                }
            }

            //提交请求数据
            Stream stream;
            stream = request.GetRequestStream();
            stream.Write(postdatabyte, 0, postdatabyte.Length);
            stream.Close();

            response = (HttpWebResponse)request.GetResponse();
            Stream strm = response.GetResponseStream();

            StreamReader sr = new StreamReader(strm, Encoding.UTF8);

            string line;

            StringBuilder sb = new StringBuilder();

            while ((line = sr.ReadLine()) != null)
            {
                sb.Append(line + Environment.NewLine);
            }
            sr.Close();
            strm.Close();
            return sb.ToString();
        }
        #endregion
#else
        public HttpClientHandler httpClient { get; private set; }

        public HttpRequestMessage requestMessage { get; private set; }

        public CustomHttpClient()
        {
            
        }

        private void Init(bool https)
        {
            this.httpClient = new HttpClientHandler()
            {
                AllowAutoRedirect = false,
                UseCookies = false
            };
            if (https)
            {
#if NET461
                ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback((sender, certificate, chain, error) =>
                {
                    return true;
                });
#else
                this.httpClient.ServerCertificateCustomValidationCallback = (message, certificate, chain, error) =>
                {
                    return true;
                };
#endif
            }
            this.requestMessage = new HttpRequestMessage();
        }


        public void Get(string url, Action<HttpResponseMessage> reponseHanlder = null, bool https = false, string[] cookies = null, Dictionary<string, string> headers = null)
        {
            var result = Task.FromResult(this.GetAsync(url, https, cookies, headers)).Result;
            reponseHanlder?.Invoke(result.Result);
        }

        public async Task<HttpResponseMessage> GetAsync(string url, bool https = false, string[] cookies = null, Dictionary<string, string> headers = null)
        {
            this.Init(https);
            using (var http = new HttpClient(this.httpClient))
            {
                if (cookies != null)
                {
                    http.DefaultRequestHeaders.Add("Cookie", string.Join("&", cookies));
                }
                if (headers != null)
                {
                    foreach (var header in headers)
                    {
                        http.DefaultRequestHeaders.Add(header.Key, header.Value);
                    }
                }
                return await http.GetAsync(url);
            }
        }

        public void Post(string url, string postData, Action<HttpResponseMessage> reponseHanlder = null, bool https = false, string[] cookies = null, Dictionary<string, string> headers = null)
        {
            var result = Task.FromResult(this.PostAsync(url, postData, https, cookies, headers)).Result;
            reponseHanlder?.Invoke(result.Result);
        }

        public async Task<HttpResponseMessage> PostAsync(string url, string postData, bool https = false, string[] cookies = null, Dictionary<string, string> headers = null)
        {
            this.Init(https);

            this.requestMessage.RequestUri = new Uri(url);
            this.requestMessage.Content = new StringContent(postData);
            this.requestMessage.Content.Headers.ContentType.MediaType = "application/x-www-form-urlencoded";
            this.requestMessage.Content.Headers.ContentType.CharSet = "utf-8";


            this.requestMessage.Method = HttpMethod.Post;
            requestMessage.Headers.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/xml"));
            requestMessage.Headers.Add("Cache-Control", "no-cache");
            if (cookies != null)
            {
                requestMessage.Headers.Add("Cookie", string.Join("&", cookies));
            }
            if (headers != null)
            {
                foreach (var header in headers)
                {
                    requestMessage.Headers.Add(header.Key, header.Value);
                }
            }

            using (var http = new HttpClient(this.httpClient))
            {
                return await http.SendAsync(this.requestMessage);
            }
        }
#endif
            }
}
